package com.social.utils;

import cn.hutool.json.JSONUtil;
import com.rabbitmq.client.Channel;
import com.social.pojo.Activity;
import com.social.service.EsActivityService;
import com.social.utils.annotation.Action;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import static com.social.constant.RabbitMqConstants.*;

/**
 * @author zero
 * @version 1.0
 * @project demo
 * @description 发送消息到es
 * @date 2023/1/8 16:21:43
 */
@Component
@Slf4j
public class ActivityReceiver {
    @Resource
    private EsActivityService esActivityService;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = QUEUE_ES_ITEM, durable = "true"),
            exchange = @Exchange(value = EXCHANGE_TOPIC_ES),
            key = {ROUTING_ES_ITEM}
    ))
    @RabbitHandler
    public void addActToEs(Message message, Channel channel){
        String json = new String(message.getBody());
        Activity activity = JSONUtil.toBean(json, Activity.class);
        System.out.println("消息已经被监听到了");
        long tag = message.getMessageProperties().getDeliveryTag();
        Action action = Action.SUCCESS;
        try {
            System.out.println("消费者RabbitDemoConsumer从RabbitMQ服务端消费消息：" + activity);
            esActivityService.addToES(activity);
        } catch (IllegalArgumentException e1) {
            e1.printStackTrace();
            //根据异常的类型判断，设置action是可重试的，还是无需重试的
            action = Action.RETRY;
        } catch (Exception e2) {
            //打印异常
            e2.printStackTrace();
            //根据异常的类型判断，设置action是可重试的，还是无需重试的
            action = Action.REJECT;
        } finally {
            try {
                if (action == Action.SUCCESS) {
                    //multiple 表示是否批量处理。true表示批量ack处理小于tag的所有消息。false则处理当前消息
                    channel.basicAck(tag, false);
                } else if (action == Action.RETRY) {
                    //Nack，拒绝策略，消息重回队列
                    channel.basicNack(tag, false, true);
                } else {
                    //Nack，拒绝策略，并且从队列中删除
                    channel.basicNack(tag, false, false);
                }
                channel.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    }

